Using a movie data export component to create a QuickTime movie file is similar in many respects to creating an AIFF file as shown in the previous example. Media data is handled differently in each case, however.
Listing 11-7 illustrates the first step, instantiating a movie data export component for video data.
Listing 7 Instantiating a movie data export component
ComponentDescription cd;
MovieExportComponent ci;
cd.componentType = MovieExportType;
cd.componentSubType = `MooV';
cd.componentManufacturer = 0;
cd.componentFlags = canMovieExportFromProcedures;
cd.componentFlagsMask = canMovieExportFromProcedures;
ci = OpenComponent(FindNextComponent(nil, &cd));
Listing 11-8 illustrates the next step: configuring the data export component to create a single output video track. The call to MovieExportAddDataSource provides the callback functions for supplying media data.
Listing 8 Configuring the movie data export component
#define kMySampleRate 2997/* 29.97 fps */
#define kMyFrameDuration 100/* one frame at 29.97 fps */
typedef struct
{
GWorldPtr gw;
ImageDescriptionHandle imageDescription;
long trackID;
}
MyReferenceRecord;
MyReferenceRecord myRef;
myRef.gw = nil;
myRef.imageDescription = nil;
MovieExportAddDataSource(ci, VideoMediaType, kMySampleRate,
&myRef.trackID, getVideoPropertyProc,
getVideoDataProc, &myRef);
At this point, operations could be added. For example, additional video tracks or sound tracks could be created. Once all the output tracks are created, the export operation takes place. This is the same as in the AIFF export example.
Listing 9 Exporting video data
StandardFileReply reply;
Handle dataRef;
// get output file from user
QTNewAlias(&reply.sfFile, (AliasHandle *)&dataRef, true);
MovieExportFromProceduresToDataRef(ci, dataRef, rAliasType);
The getVideoPropertyProc function returns information about the output track's properties (for example, the compression format). If the function doesn't return a value for a particular property, the exporter will choose a default value based (usually) on the source data format. In Listing 11-10 , dimensions are set to 160x120 and the compression format is set to JPEG. All other properties are unspecified.
Listing 10 Obtaining information about output track properties
pascal OSErr getVideoPropertyProc(void *refcon, long trackID, OSType propertyType, void
*propertyValue)
{
OSErr err = noErr;
switch (propertyType) {
case meWidth:
*(Fixed *)propertyValue = 160L << 16;
break;
case meHeight:
*(Fixed *)propertyValue = 120L << 16;
break;
case scSpatialSettingsType:
{
SCSpatialSettings *ss = propertyValue;
ss->codecType = kJPEGCodecType;
ss->codec = 0;
ss->depth = 0;
ss->spatialQuality = codecNormalQuality;
}
break;
default:
err = paramErr;
break;
}
return err;
}
The videoGetData function provides video frames to the export operation. In the example in Listing 11-11 , the same blank frame is returned for each request. The export operation ends when this function returns eofErr . Any data allocated by videoGetProc must be disposed of after the export operation is complete.
Listing 11 Providing video frames for export
pascal OSErr videoGetData(void *refCon,
MovieExportGetDataParams *params)
{
OSErr err = noErr;
MyReferenceRecord *myRef = (MyReferenceRecord *)refCon;
TimeRecord tr;
if (params->requestedTime > kMySampleRate * 10)
return eofErr;// end of data after 10 seconds
if (!myRef->gw) {
Rect r;
CGrafPtr savePort;
GDHandle saveGD;
SetRect(&r, 0, 0, 320, 240);
NewGWorld(&myRef->gw, 32, &r, nil, nil, 0);
LockPixels(myRef ->gw->portPixMap);
MakeImageDescriptionForGWorld(myRef->gw,
&myRef->imageDescription);
GetGWorld(&savePort, &saveGD);
SetGWorld(myRef->gw, nil);
EraseRect(&r);
SetGWorld(savePort, saveGD);
}
params->dataPtr = GetPixBaseAddr(myRef->gw->portPixMap);
params->dataSize = (**myRef->imageDescription).dataSize;
params->actualTime = params->requestedTime;
params->descType = VideoMediaType;
params->descSeed = 1;
params->desc = (SampleDescriptionHandle)
myRef->imageDescription;
params->durationPerSample = kMyFrameDuration;
params->sampleFlags = 0;
bail:
return err;
}
| Previous | Chapter contents | Chapter top | Section top | Next |